package redis

import (
	"gitee.com/tangrx/go-admin/utils/config"
	"github.com/gomodule/redigo/redis"
	"log"
	"time"
)

const REDIS_KEY string = "redis"
const REDIS_AUTH_KEY string = "redis-auth"

var redisPool *redis.Pool // redis 连接池
func init() {
	redisPool = RedisPollInit()
}
func Do(commandName string, args ...interface{}) (interface{}, error) {
	conn := redisPool.Get()
	defer conn.Close()
	data, err := conn.Do(commandName, args...)
	if err != nil {
		log.Println(err)
		return nil, err
	}
	return data, nil
}

// Send writes the command to the client's output buffer.
func Send(commandName string, args ...interface{}) error {
	conn := redisPool.Get()
	defer conn.Close()
	err := conn.Send(commandName, args...)
	return err
}

// Flush flushes the output buffer to the Redis server.
func Flush() error {
	conn := redisPool.Get()
	defer conn.Close()
	err := conn.Flush()
	return err
}

// Receive receives a single reply from the Redis server
func Receive() (interface{}, error) {
	conn := redisPool.Get()
	defer conn.Close()
	data, err := conn.Receive()
	return data, err
}

func RedisPollInit() *redis.Pool {
	return &redis.Pool{
		MaxIdle:   3,
		MaxActive: 5,
		Dial: func() (redis.Conn, error) {
			addr := "127.0.0.1:6379"

			if len(config.GetStr(REDIS_KEY)) > 0 {
				addr = config.GetStr(REDIS_KEY)
			}
			c, err := redis.Dial("tcp", addr)
			if err != nil {
				return nil, err
			}
			auth := ""
			if len(config.GetStr(REDIS_AUTH_KEY)) > 0 {
				auth = config.GetStr(REDIS_AUTH_KEY)
			}
			if len(auth) > 0 {
				_, err = c.Do("AUTH", auth)
				if err != nil {
					c.Close()
					return nil, err
				}
			}

			return c, err
		},
	}
}

func Put(key string, val string, timeout time.Duration) error {
	conn := redisPool.Get()
	defer conn.Close()
	_, err := Do("SETEX", key, int64(timeout/time.Second), val)
	return err
}

func Get(key string) string {
	if v, err := redis.String(Do("GET", key)); err == nil {
		return v
	}
	return ""
}

// 更新过期时间
func EXPIRE(key string, timeout time.Duration) error {
	conn := redisPool.Get()
	defer conn.Close()
	_, err := Do("EXPIRE", key, int64(timeout/time.Second))
	return err
}
